<template>
  <!-- 表单信息 -->
  <div class="form-container">
    <div class="box">
      <div class="form-left relative" :style="{ width: formLeft }" @mousedown="handleLeftDown">
        <div class="resize-shrink-sidebar" id="approval-form-left" title="收缩侧边栏">
          <span class="shrink-sidebar-text">⋮</span>
        </div>
        <div class="left-title">
          <NodeHead :nodeName="t('表单信息')" v-show="showPanel" />
          <div @click="changeShowPanel" class="in-or-out">
            <component :is="fewerPanelComponent" />
          </div>
        </div>
        <div class="left-box">
          <div
            v-for="(item, index) in forms.configs"
            :key="index"
            :class="activeIndex == index ? 'form-name actived' : 'form-name'"
          >
            <span :class="item.validate ? 'dot' : 'dot validate'"></span>
            <div class="icon-box"> <IconFontSymbol icon="formItem" /> </div
            ><span @click="changeActiveIndex(index)" v-show="showPanel">{{ item.formName }}</span>
          </div>
        </div>
      </div>
      <div class="form-right" :style="{ paddingLeft: formRight }">
        <div v-for="(item, index) in forms.configs" :key="index" :tab="item.formName">
          <SimpleForm
            class="form-box"
            :ref="setItemRef"
            v-show="activeIndex == index"
            :formProps="item.formProps"
            :formModel="item.formModel"
            :isWorkFlow="true"
          />
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
  import { buildOption } from '/@/utils/helper/designHelper';
  import { FormProps } from '/@/components/Form';
  import SimpleForm from '/@/components/SimpleForm/src/SimpleForm.vue';
  import { FewerLeft, FewerRight } from '/@/components/ModalPanel';
  import { NodeHead } from '/@/components/ModalPanel/index';
  import IconFontSymbol from '/@/components/IconFontSymbol/Index.vue';
  import { onBeforeUpdate, nextTick, onMounted, reactive, computed, ref } from 'vue';
  import { TaskApproveOpinion, ValidateForms } from '/@/model/workflow/bpmnConfig';
  import { cloneDeep } from 'lodash-es';
  import { separator } from '../../../design/bpmn/config/info';
  import { useI18n } from '/@/hooks/web/useI18n';
  import { GeneratorConfig } from '/@/model/generator/generatorConfig';
  import { apiConfigFunc } from '/@/utils/event/design';
  import { execute } from '/@/api/liteflow';
  import { FormEventColumnConfig } from '/@/model/generator/formEventConfig';
  const { t } = useI18n();
  const props = withDefaults(
    defineProps<{
      disabled: boolean | undefined;
      formInfos: Array<any>;
      opinions?: Array<TaskApproveOpinion> | undefined;
      opinionsComponents?: Array<string> | undefined;
      formAssignmentData?: null | Recordable;
    }>(),
    {
      disabled: false,
      formInfos: () => {
        return [];
      },
    },
  );

  const emits = defineEmits(['getFormConfigs']);

  let formLeft = ref('24%');
  let formRight = ref('calc(24% + 10px)');
  let showPanel = ref(true);
  let uploadComponent: { ids: Array<string> } = reactive({ ids: [] });
  let fewerPanelComponent = computed(() => {
    return showPanel.value ? FewerLeft : FewerRight;
  });

  let activeIndex = ref(0);
  let itemRefs = ref([]) as any;
  const setItemRef = (el: never) => {
    itemRefs.value.push(el);
  };
  function showRightBox() {
    formLeft.value = '24%';
    formRight.value = 'calc(24% + 10px)';
  }
  function hideRightBox() {
    formLeft.value = '58px';
    formRight.value = '78px';
  }
  function changeShowPanel() {
    showPanel.value = !showPanel.value;
    if (showPanel.value) {
      showRightBox();
    } else {
      hideRightBox();
    }
  }
  onBeforeUpdate(() => {
    itemRefs.value = [];
  });
  let forms: {
    formModels: Array<Recordable>;
    configs: Array<{
      formName: string;
      formProps: {};
      formModel: Recordable;
      formKey: string;
      validate: boolean;
      formType: number;
    }>;
    formEventConfigs: FormEventColumnConfig[];
  } = reactive({
    formModels: [],
    configs: [],
    formEventConfigs: [],
  });
  onMounted(async () => {
    props.formInfos.forEach(async (element) => {
      let formModels = {};
      if (element.formData) {
        formModels = cloneDeep(element.formData);
      }
      // 参数赋值[赋值权限最大]
      if (props.formAssignmentData) {
        if (props.formAssignmentData[element.formConfig.formId]) {
          formModels = { ...formModels, ...props.formAssignmentData[element.formConfig.formId] };
        }
      }
      forms.formModels.push(formModels);
      const model = JSON.parse(element.formJson) as GeneratorConfig;
      const { formJson, formEventConfig } = model;
      if (formEventConfig) {
        forms.formEventConfigs.push(formEventConfig);

        //初始化表单
        executeFormEvent(formEventConfig[0], formModels);
        //加载表单
        executeFormEvent(formEventConfig[2], formModels);

        //TODO 暂不放开 工作流没有获取表单数据这个步骤 获取表单数据
        // executeFormEvent(formEventConfig[1], formModels);
      }
      let formKey = element.formConfig.key;

      let config = {
        formName: element.formConfig.formName,
        formProps: {},
        formModel: {},
        formKey,
        validate: true,
        formType: element.formType,
      };

      let buildOptionJson = handlerFormPermission(
        buildOption(formJson, false), //工作流中 无论系统表单 自定义表单 都统一走 后端 自定义表单 增删查改的逻辑  所以无需转驼峰
        element.formConfig.children,
        element.formConfig.key,
      );

      if (buildOptionJson.schemas) {
        config.formProps = buildOptionJson;
        forms.configs.push(config);
      }
    });
    await nextTick();
    setFormModel();
    emits('getFormConfigs', forms.configs.length ? forms.configs[activeIndex.value] : null);
  });

  function setFormModel() {
    for (let index = 0; index < itemRefs.value.length; index++) {
      if (itemRefs.value[index]) {
        itemRefs.value[index].setFieldsValue(forms.formModels[index]);
      }
    }
  }

  function executeFormEvent(formEventConfig, formModel) {
    if (!formEventConfig.length) return;
    formEventConfig.map((x) => {
      x.nodeInfo?.processEvent?.map(async (config) => {
        if (config.operateType === 'api') {
          await apiConfigFunc(config.operateConfig, true, formModel);
        } else if (config.operateType === 'liteflow') {
          await execute(config.operateConfig, formModel);
        }
      });
    });
  }

  async function setFormData(formData) {
    await nextTick();
    forms.formModels = formData;
    setFormModel();
  }
  function getPermissionConfigMap(children) {
    let map = new Map();
    children.forEach((element) => {
      map.set(element.key, element);
    });
    return map;
  }
  function handlerFormPermission(buildOptionJson: FormProps, children, formKey) {
    let permissionConfigMap = getPermissionConfigMap(children);
    const formShow: Number = 0; //表单是否有显示的组件，有则大于0
    buildOptionJson.schemas = schemeList(
      buildOptionJson.schemas,
      permissionConfigMap,
      formKey,
      formShow,
    );

    return buildOptionJson;
  }

  function schemeList(schemas, permissionConfigMap, formKey, formShow, tableName?) {
    schemas = schemas.map((schema) => {
      if (['Card', 'Grid', 'Tab'].includes(schema.component)) {
        formShow += 1;
        if (schema.children && schema.children.length > 0) {
          schema.children.forEach((ele2) => {
            if (ele2.list && ele2.list.length > 0) {
              ele2.list = schemeList(ele2.list, permissionConfigMap, formKey, formShow, tableName);
              // let showTrueList = ele2.list.filter((item) => {
              //   return item.show;
              // });
              // if (showTrueList.length > 0) {
              //   ele2.show = true;
              // } else {
              //   ele2.show = false;
              // }
            }
          });
        }
      } else if (schema.component == 'SubForm') {
        if (
          schema.componentProps &&
          schema.componentProps.columns &&
          schema.componentProps.columns.length > 0
        ) {
          let permissionConfig = permissionConfigMap.has(schema.key)
            ? permissionConfigMap.get(schema.key)
            : null;

          // 查看流程
          if (props.disabled) {
            schema.dynamicDisabled = true;
          }
          if (!permissionConfig?.view) {
            schema.show = false;
          } else {
            formShow += 1;
          }
          schema.componentProps.columns = schema.componentProps.columns.map((ele3) => {
            const tableItemPermissionConfig = permissionConfig.children.find((x) => {
              if (x.fieldId) {
                return x.fieldId === ele3.dataIndex;
              }
              if (x.key) {
                return x.key === ele3.key;
              }
            });

            return getSchemePermissionItem(ele3, tableItemPermissionConfig, formKey);
          });
        }
      } else if (schema.component == 'OneForOne') {
        let permissionConfig = permissionConfigMap.has(schema.key)
          ? permissionConfigMap.get(schema.key)
          : null;
        if (!permissionConfig?.view) {
          schema.show = false;
        } else {
          formShow += 1;
        }
        if (schema.componentProps?.childSchemas?.length > 0) {
          let onePermissionConfigMap = getPermissionConfigMap(permissionConfig.children);
          schema.componentProps.childSchemas = schemeList(
            schema.componentProps.childSchemas,
            onePermissionConfigMap,
            formKey,
            formShow,
            schema.field,
          );
        }
      } else {
        let permissionConfig = permissionConfigMap.has(schema.key)
          ? permissionConfigMap.get(schema.key)
          : null;

        schema = getSchemePermissionItem(schema, permissionConfig, formKey, tableName);
        if (permissionConfig?.view) {
          formShow += 1;
        }
      }

      return schema;
    });

    return formShow > 0 ? schemas : null;
  }

  function getSchemePermissionItem(schema, permissionConfig, formKey, tableName?) {
    if (permissionConfig) {
      //查看
      schema.show = permissionConfig.view;
      // 必填

      if (schema.componentProps) schema.componentProps.required = permissionConfig.required;
      schema.required = permissionConfig.required;
      //编辑

      if (schema.componentProps) schema.componentProps.disabled = !permissionConfig.edit;
      schema.dynamicDisabled = !permissionConfig.edit;

      // 查看流程
      if (props.disabled) {
        schema.dynamicDisabled = true;
      }
    } else {
      schema.show = false;
      schema.dynamicDisabled = true;
    }
    // 修改意见簿
    if (schema.component == 'Opinion') {
      let key = formKey + separator + schema.key;
      if (props.opinionsComponents?.includes(key)) {
        schema.defaultValue = props.opinions;
      }
    }
    // 上传组件集合
    if (schema.component == 'Upload') {
      let key = '';
      if (tableName) {
        key = formKey + separator + tableName + separator + schema.field;
      } else {
        key = formKey + separator + schema.field;
      }

      uploadComponent.ids.push(key);
    }
    if (permissionConfig?.isSubTable) {
      // 子表单上传组件集合
      if (schema.componentType == 'Upload') {
        let key =
          formKey + separator + permissionConfig.tableName + separator + permissionConfig.fieldId;

        uploadComponent.ids.push(key);
      }
    }
    return schema;
  }

  function changeActiveIndex(index: number) {
    activeIndex.value = index;
    emits('getFormConfigs', forms.configs[activeIndex.value]);
  }
  // 获取上传组件的字段值集合
  function getUploadComponentIds() {
    return uploadComponent.ids;
  }
  async function validateForm() {
    let validateForms: ValidateForms = [];
    for (let index = 0; index < itemRefs.value.length; index++) {
      if (itemRefs.value[index]) {
        try {
          await itemRefs.value[index]?.validate();
          validateForms.push({
            validate: true,
            msgs: [],
          });
          forms.configs[index].validate = true;
        } catch (error: any | Array<{ errors: Array<string>; name: Array<string> }>) {
          validateForms.push({
            validate: false,
            msgs: error?.errorFields,
          });
          forms.configs[index].validate = false;
        }
      }
    }
    return validateForms;
  }
  async function getFormModels() {
    let formModes = {};

    forms.configs.forEach((ele) => {
      formModes[ele.formKey] = ele.formModel;
    });
    forms.formEventConfigs.forEach((ele, i) => {
      //此组件 获取数据 就是为了提交表单 所以 表单提交数据 事件 就此处执行
      executeFormEvent(ele[3], forms.configs[i]?.formModel);
    });
    return formModes;
  }
  function handleLeftDown(e) {
    let resize = document.getElementById('approval-form-left') as any;
    let startX = e.clientX;
    let left = resize?.offsetLeft || 0;

    document.onmousemove = function (e) {
      let endX = e.clientX;
      let moveLen = left + (endX - startX);
      if (moveLen <= 110) {
        showPanel.value = false;
      } else {
        showPanel.value = true;
      }
      if (moveLen <= 58) moveLen = 58;
      formLeft.value = moveLen + 'px';
      formRight.value = moveLen + 20 + 'px';
    };
    document.onmouseup = function () {
      document.onmousemove = null;
      document.onmouseup = null;
      resize.releaseCapture && resize.releaseCapture();
    };
  }
  defineExpose({
    validateForm,
    getFormModels,
    setFormData,
    getUploadComponentIds,
  });
</script>

<style lang="less" scoped>
  .form-container {
    display: flex;
    height: 100vh;
    margin-top: -10px;
  }

  .box {
    width: 100%;

    .form-left {
      float: left;
      height: 100vh;
      box-shadow: 5px 5px 5px rgb(0 0 0 / 10%);
      z-index: 9998;

      .resize-shrink-sidebar {
        cursor: col-resize;
        display: flex;
        justify-content: center;
        align-items: center;
        position: absolute;
        top: 0;
        bottom: 0;
        right: 0;
        z-index: 9999;

        .shrink-sidebar-text {
          padding: 0 2px;
          background: #f2f2f2;
          border-radius: 10px;
        }
      }

      .left-box {
        margin-right: 10px;
        border-right: 1px solid #f0f0f0;
        height: 80vh;
      }

      span {
        font-size: 16px;
        font-weight: 500;
        padding-left: 4px;
      }

      .form-name {
        height: 36px;
        display: flex;
        align-items: center;
        font-size: 14px;
        cursor: pointer;
        color: rgb(102 102 102 / 99.6%);
        margin-right: -2px;
        padding-left: 4px;
      }

      .actived {
        border-right: 1px solid #5e95ff;
      }

      .dot {
        width: 10px;
        height: 10px;
        border-radius: 50%;
        background-color: transparent;
        margin-right: 4px;
      }

      .validate {
        background-color: @clear-color;
      }

      .icon-box {
        font-size: 16px;
        margin-right: 4px;
      }

      .left-title {
        display: flex;
        justify-content: space-between;
        align-items: center;
        position: relative;
        padding: 10px 4px 10px 0;
        top: 0;
        left: 0;

        .in-or-out {
          position: absolute;
          right: 10px;
        }
      }
    }

    .form-box {
      overflow: auto;
      height: calc(100vh - 120px);
    }

    .form-right {
      width: 100%;
      padding-top: 20px;
    }
  }
</style>
